package ar.edu.unq.wannaplay.helpers;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import ar.edu.unq.wannaplay.calendareable.Project;
import ar.edu.unq.wannaplay.employee.Employee;
import ar.edu.unq.wannaplay.utils.Pair;
import ar.edu.unq.wannaplay.utils.SortManager;

public class EmployeeRecommender implements Serializable {
    private static final long serialVersionUID = 1L;

    private RecommenderStrategy strategy;

    public EmployeeRecommender() {
        // default
        this.setStrategy(new SkillsAndIntervalsStrategy());
    }

    public List<Pair<Employee, Float>> recommendEmployeesForProject(final Project project,
            final List<Employee> employees) {
        Map<Float, List<Employee>> percentageMap = new HashMap<Float, List<Employee>>();
        for (Employee e : employees) {
            Float percentage = strategy.getSatisfactionPercentage(e, project);
            List<Employee> percEmployees = percentageMap.get(percentage);
            this.addToPercentageMap(percentageMap, e, percentage, percEmployees);
        }

        return this.percentageMapToPriorityList(percentageMap);
    }

    private void addToPercentageMap(final Map<Float, List<Employee>> percentageMap, final Employee employee,
            final Float percentage, final List<Employee> percEmployees) {
        List<Employee> newList;
        if (percEmployees == null) {
            newList = new ArrayList<Employee>();
            newList.add(employee);
            percentageMap.put(percentage, newList);
        } else {
            percentageMap.get(percentage).add(employee);
        }
    }

    private List<Pair<Employee, Float>> percentageMapToPriorityList(final Map<Float, List<Employee>> percentageMap) {
        List<Pair<Employee, Float>> recommended = new ArrayList<Pair<Employee, Float>>();

        for (Entry<Float, List<Employee>> entrySet : percentageMap.entrySet()) {
            for (Employee e : entrySet.getValue()) {
                recommended.add(this.creaPairForPriorityList(entrySet, e));
            }
        }

        return SortManager.sortPairListBySecond(recommended);
    }

    private Pair<Employee, Float> creaPairForPriorityList(final Entry<Float, List<Employee>> entrySet,
            final Employee employee) {
        return new Pair<Employee, Float>(employee, entrySet.getKey());
    }

    public RecommenderStrategy getStrategy() {
        return strategy;
    }

    public void setStrategy(final RecommenderStrategy strategy) {
        this.strategy = strategy;
    }
}
